home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / LookAtThat!.sit / LookAtThat! / source code / main.c next >
C/C++ Source or Header  |  1997-06-28  |  21KB  |  1,001 lines

  1. // main.c
  2.  
  3. #include <A4Stuff.h>
  4. #include <Resources.h>
  5. #include <Windows.h>
  6. #include <Quickdraw.h>
  7. #include <Traps.h>
  8. #include <OSUtils.h>
  9. #include "Offscreen.h"
  10.  
  11.  
  12. #define    Increment    1
  13. #define    PADDLESPEED    3
  14. #define BALLSPEED    1
  15.  
  16. #define SLEEPTIME    1
  17.  
  18. #define    WidthCalc    5
  19. #define    HeightCalc    22
  20.  
  21. #define    BricksH    8
  22. #define    BricksV    4
  23. #define kHit    1
  24. #define    kSafe    0
  25.  
  26. #define    KeyMapLoMem ((unsigned char *)0x174)
  27. #define    KeyIsDown(key)    (( KeyMapLoMem[ key >> 3 ] >> ( key & 7)) &1)
  28.  
  29. #define    aKey    0x00
  30. #define    sKey    0x01
  31. #define    fourKey    0x56
  32. #define fiveKey 0x57
  33. #define    sixKey    0x58
  34. #define threeKey 0x55
  35. #define oneKey    0x53
  36.  
  37. Point        pongSpeed;
  38. Rect        ballRect, paddleRectOne, paddleRectTwo;
  39. GWorldPtr    ball = nil;
  40. GWorldPtr    paddleOne = nil, paddleTwo = nil;
  41. GWorldPtr    pongGWorld = nil;
  42. WindowPtr    pongWindow = nil;
  43. Boolean        gTakeOver = TRUE;
  44. Boolean        gDone = FALSE;
  45.  
  46.  
  47. Point        boSpeed;
  48. Rect        boBallRect, boPaddleRect;
  49. GWorldPtr    boBall = nil;
  50. GWorldPtr    boPaddle = nil;
  51. GWorldPtr    brickWorld = nil;
  52. GWorldPtr    boGWorld = nil;
  53. WindowPtr    breakoutWindow = nil;
  54. Boolean        gBOTakeOver = TRUE;
  55. Boolean        gBODone = FALSE;
  56.  
  57.  
  58.  
  59. unsigned long    oldTicks = 0L;
  60.  
  61. RGBColor    white = { 65535, 65535, 65535 };
  62. RGBColor    black = { 0, 0, 0 };
  63. RGBColor    green = { 0 , 17476 , 0 };
  64. RGBColor    blue = { 0 , 0 , 17476 };
  65. RGBColor    red = { 17476 , 0 , 0 };
  66. RGBColor    lightgreen = { 0 , 48059 , 0 };
  67. RGBColor     lightblue = { 13107 , 26214 , 65535 };
  68. RGBColor    lightred = { 34952 , 0 , 0 };
  69.  
  70. short    BrickState[BricksH][BricksV];
  71. Rect    Bricks[BricksH][BricksV];
  72. short    BrickWidth, BrickHeight;
  73. Rect    brickRect, oldBall, oldPaddle;
  74.  
  75.  
  76. void    InitPong(WindowPtr theWindow);
  77. void    DisposePong(void);
  78. void    DoPong(WindowPtr theWindow, EventRecord * theEvent);
  79. void    UpdateBall(WindowPtr window);
  80. void    UpdatePaddles(WindowPtr    window, EventRecord * theEvent);
  81. void    CreateBall(WindowPtr window);
  82. void    CreatePaddles(WindowPtr window);
  83.  
  84.  
  85. void    InitBreakOut(WindowPtr theWindow);
  86. void    DisposeBreakOut(void);
  87. void    DoBreakOut(WindowPtr theWindow, EventRecord * theEvent);
  88. void    UpdateBreakoutBall(WindowPtr window);
  89. void    UpdateBreakoutPaddle(WindowPtr    window, EventRecord * theEvent);
  90. void    CreateBreakoutBall(WindowPtr window);
  91. void    CreateBreakoutPaddle(WindowPtr window);
  92. void    CreateBricks(WindowPtr    window);
  93. void    DrawBricks(WindowPtr theWindow);
  94. void    CheckCollide(WindowPtr theWindow);
  95.  
  96.  
  97. typedef pascal void (*endUpdate)(WindowPtr theWindow);
  98. endUpdate gEndUpdateAddr;
  99. pascal void MyEndUpdate(WindowPtr theWindow);
  100.  
  101. typedef pascal void (*closeWindow)(WindowPtr theWindow);
  102. closeWindow gCloseWindowAddr;
  103. pascal void MyCloseWindow(WindowPtr theWindow);
  104.  
  105. typedef pascal void (*showHide)(WindowPtr theWindow, Boolean showFlag);
  106. showHide gShowHideAddr;
  107. pascal void MyShowHide(WindowPtr theWindow, Boolean showFlag);
  108.  
  109. typedef pascal void (*drawControls)(WindowPtr theWindow);
  110. drawControls gDrawControlsAddr;
  111. pascal void MyDrawControls(WindowPtr theWindow);
  112.  
  113. typedef pascal Boolean (*getNextEvent)(short mask, EventRecord *theEvent);
  114. getNextEvent gGetNextEventAddr;
  115. pascal Boolean MyGetNextEvent(short mask, EventRecord *theEvent);
  116.  
  117.  
  118. void main(void)
  119. {
  120.     Handle                init;
  121.  
  122.     EnterCodeResource();
  123.     
  124.     init = Get1Resource('INIT', 0);
  125.     if (init == nil)
  126.     {
  127.         DebugStr("\pOh shit");
  128.         ExitCodeResource();
  129.         return;
  130.     }
  131.     DetachResource(init);
  132.     
  133.     gEndUpdateAddr = (endUpdate)NGetTrapAddress(_EndUpDate, ToolTrap);
  134.     NSetTrapAddress((UniversalProcPtr)MyEndUpdate, _EndUpDate, ToolTrap);
  135.  
  136.     gCloseWindowAddr = (closeWindow)NGetTrapAddress(_CloseWindow, ToolTrap);
  137.     NSetTrapAddress((UniversalProcPtr)MyCloseWindow, _CloseWindow, ToolTrap);
  138.  
  139.     gShowHideAddr = (showHide)NGetTrapAddress(_ShowHide, ToolTrap);
  140.     NSetTrapAddress((UniversalProcPtr)MyShowHide, _ShowHide, ToolTrap);
  141.  
  142.     gGetNextEventAddr = (getNextEvent)NGetTrapAddress(_GetNextEvent, ToolTrap);
  143.     NSetTrapAddress((UniversalProcPtr)MyGetNextEvent, _GetNextEvent, ToolTrap);
  144.  
  145.     gDrawControlsAddr = (drawControls)NGetTrapAddress(_DrawControls, ToolTrap);
  146.     NSetTrapAddress((UniversalProcPtr)MyDrawControls, _DrawControls, ToolTrap);
  147.  
  148.     ExitCodeResource();
  149. }
  150.  
  151.  
  152.  
  153. pascal void MyCloseWindow(WindowPtr theWindow)
  154. {
  155.     EnterCodeResource();
  156.     
  157.     if (theWindow == pongWindow)
  158.     {
  159.         DisposePong();
  160.         pongWindow = nil;
  161.         oldTicks = 0L;
  162.         gTakeOver = TRUE;
  163.         gDone = FALSE;
  164.     }
  165.     else if (theWindow == breakoutWindow)
  166.     {
  167.         DisposeBreakOut();
  168.         breakoutWindow = nil;
  169.         oldTicks = 0L;
  170.         gBOTakeOver = TRUE;
  171.         gBODone = FALSE;
  172.     }
  173.     gCloseWindowAddr(theWindow);
  174.         
  175.     ExitCodeResource();
  176. }
  177.  
  178.  
  179. pascal void MyShowHide(WindowPtr theWindow, Boolean showFlag)
  180. {
  181.     EnterCodeResource();
  182.     
  183.     gShowHideAddr(theWindow, showFlag);
  184.     
  185.     if (showFlag == TRUE)
  186.     {
  187.         if (pongWindow == nil)
  188.         {
  189.             if (EqualString(*(((WindowPeek)theWindow)->titleHandle), "\pPONG!", TRUE, TRUE))
  190.             {
  191.                 InitPong(theWindow);
  192.             }
  193.         }
  194.         if (breakoutWindow == nil)
  195.         {
  196.             if (EqualString(*(((WindowPeek)theWindow)->titleHandle), "\pWOZ!", TRUE, TRUE))
  197.             {
  198.                 InitBreakOut(theWindow);
  199.             }
  200.         }
  201.     }
  202.         
  203.     ExitCodeResource();
  204. }
  205.  
  206.  
  207. pascal void MyDrawControls(WindowPtr theWindow)
  208. {
  209.     EnterCodeResource();
  210.     
  211.     if (theWindow != pongWindow && theWindow != breakoutWindow)
  212.         gDrawControlsAddr(theWindow);
  213.         
  214.     ExitCodeResource();
  215. }
  216.  
  217. pascal Boolean MyGetNextEvent(short eventMask, EventRecord *theEvent)
  218. {
  219.     Boolean                    result;
  220.     WindowPtr                theWindow;
  221.     GrafPtr                    myPort;
  222.     getNextEvent            gne;
  223.     unsigned long            ticks;
  224.     
  225.     
  226.     EnterCodeResource();
  227.     
  228.     gne = gGetNextEventAddr;
  229.     ExitCodeResource();
  230.     result = gne(eventMask, theEvent);
  231.     oldA4 = SetCurrentA4();
  232.     
  233.     if (theEvent->what == keyDown && (char) theEvent->message == '*')
  234.         Debugger();
  235.     
  236.     
  237.     theWindow = pongWindow;
  238.     
  239.     if (theWindow != nil/* && theWindow == pongWindow*/)
  240.     {
  241.         if (!EqualRect(&pongGWorld->portRect, &theWindow->portRect))
  242.             DisposePong();
  243.             
  244.         if (pongGWorld == nil)
  245.             InitPong(theWindow);
  246.             
  247.         GetPort(&myPort);
  248.         SetPort((GrafPtr)theWindow);
  249.         
  250.         if (gTakeOver)
  251.         {
  252.             if (gDone && KeyIsDown(threeKey))
  253.                 gDone = FALSE;
  254.                 
  255.             while (!gDone)
  256.             {
  257.                 if (KeyIsDown(oneKey))
  258.                 {
  259.                     gTakeOver = !gTakeOver;
  260.                     gDone = TRUE;
  261.                 }
  262.                     
  263.                 if (KeyIsDown(fiveKey))
  264.                     gDone = TRUE;
  265.                     
  266.                 ticks = TickCount();
  267.                 
  268.                 if (ticks - oldTicks > 0)
  269.                 {
  270.                     oldTicks = ticks;
  271.                     DoPong(theWindow, theEvent);
  272.                 }
  273.                 
  274.                 EventAvail(0, theEvent);
  275.             }
  276.         }
  277.         else
  278.             DoPong(theWindow, theEvent);
  279.             
  280.         SetPort(myPort);
  281.     }
  282.     
  283.     theWindow = breakoutWindow;
  284.     
  285.     if (theWindow != nil/* && theWindow == pongWindow*/)
  286.     {
  287.         if (!EqualRect(&boGWorld->portRect, &theWindow->portRect))
  288.             DisposeBreakOut();
  289.             
  290.         if (boGWorld == nil)
  291.             InitBreakOut(theWindow);
  292.             
  293.         GetPort(&myPort);
  294.         SetPort((GrafPtr)theWindow);
  295.         
  296.         if (gBOTakeOver)
  297.         {
  298.             if (gBODone && KeyIsDown(threeKey))
  299.                 gBODone = FALSE;
  300.                 
  301.             while (!gBODone)
  302.             {
  303.                 if (KeyIsDown(oneKey))
  304.                 {
  305.                     gBOTakeOver = !gBOTakeOver;
  306.                     gBODone = TRUE;
  307.                 }
  308.                     
  309.                 if (KeyIsDown(fiveKey))
  310.                     gBODone = TRUE;
  311.                     
  312.                 ticks = TickCount();
  313.                 
  314.                 if (ticks - oldTicks > 0)
  315.                 {
  316.                     oldTicks = ticks;
  317.                     DoBreakOut(theWindow, theEvent);
  318.                 }
  319.                 
  320.                 EventAvail(0, theEvent);
  321.             }
  322.         }
  323.         else
  324.             DoBreakOut(theWindow, theEvent);
  325.             
  326.         SetPort(myPort);
  327.     }
  328.  
  329.     ExitCodeResource();
  330.  
  331.     return result;
  332. }
  333.  
  334.  
  335.  
  336. pascal void MyEndUpdate(WindowPtr theWindow)
  337. {
  338.     GrafPtr        oldPort;
  339.  
  340.  
  341.     EnterCodeResource();
  342.     
  343.     GetPort(&oldPort);
  344.     
  345.     gEndUpdateAddr(theWindow);
  346.     
  347.     SetPort((GrafPtr)theWindow);
  348.     if (theWindow == pongWindow)
  349.     {
  350.         RGBForeColor(&black);
  351.         PaintRect(&theWindow->portRect);
  352.         DoPong(theWindow, nil);
  353.     }
  354.     if (theWindow == breakoutWindow)
  355.     {
  356.         RGBForeColor(&black);
  357.         PaintRect(&theWindow->portRect);
  358.         DoBreakOut(theWindow, nil);
  359.     }
  360.     SetPort(oldPort);
  361.     
  362.     ExitCodeResource();
  363. }
  364.  
  365.  
  366. #pragma mark -
  367.  
  368. void DoPong(WindowPtr theWindow, EventRecord * theEvent)
  369. {    
  370.     UpdatePaddles(theWindow, theEvent);
  371.     UpdateBall(theWindow);
  372. }
  373.  
  374.  
  375. void UpdatePaddles(WindowPtr theWindow, EventRecord * theEvent)
  376. {
  377.     Boolean            handled = FALSE;
  378.     
  379.     
  380.     if(KeyIsDown(aKey))
  381.     {
  382.         if(paddleRectOne.left > 0)
  383.                     OffsetRect(&paddleRectOne, -PADDLESPEED, 0);
  384.         handled = TRUE;
  385.     }
  386.     if(KeyIsDown(sKey))
  387.     {
  388.         if(paddleRectOne.right < theWindow->portRect.right)
  389.                     OffsetRect(&paddleRectOne, PADDLESPEED, 0);
  390.         handled = TRUE;
  391.     }
  392.     if(KeyIsDown(fourKey))
  393.     {
  394.         if(paddleRectTwo.left > 0)
  395.                     OffsetRect(&paddleRectTwo, -PADDLESPEED, 0);
  396.         handled = TRUE;
  397.     }
  398.     if(KeyIsDown(sixKey))
  399.     {
  400.         if(paddleRectTwo.right < theWindow->portRect.right)
  401.                     OffsetRect(&paddleRectTwo, PADDLESPEED, 0);
  402.         handled = TRUE;
  403.     }
  404.     if (KeyIsDown(fiveKey) || KeyIsDown(threeKey) || KeyIsDown(oneKey))
  405.         handled = TRUE;
  406.     
  407.  
  408.  
  409.     RGBBackColor(&white);
  410.     CopyBits(    &((GrafPtr)paddleOne)->portBits,
  411.                     &((GrafPtr)theWindow)->portBits,
  412.                     &paddleOne->portRect,
  413.                     &paddleRectOne,
  414.                     0,
  415.                     NULL);
  416.                         
  417.     RGBBackColor(&white);
  418.     CopyBits(    &((GrafPtr)paddleTwo)->portBits,
  419.                     &((GrafPtr)theWindow)->portBits,
  420.                     &paddleTwo->portRect,
  421.                     &paddleRectTwo,
  422.                     0,
  423.                     NULL);
  424.                     
  425.     if (theEvent != nil && handled)
  426.     {
  427.         theEvent->what = nullEvent;
  428.     }
  429. }
  430.  
  431. void UpdateBall(WindowPtr theWindow)
  432. {    
  433.     Rect    where;
  434.     short    center1,center2,offset1,offset2, offset3;
  435.     
  436.  
  437.     if(ballRect.right >= theWindow->portRect.right)
  438.         pongSpeed.h *= -1;
  439.     if(ballRect.left <= 0)
  440.         pongSpeed.h *= -1;
  441.     if(ballRect.bottom >= theWindow->portRect.bottom)
  442.         pongSpeed.v *= -1;
  443.     if(ballRect.top <= 0)
  444.         pongSpeed.v *= -1;
  445.     
  446.     if(SectRect(&ballRect, &paddleRectOne,&where))
  447.     {
  448.         if(ballRect.bottom-pongSpeed.v <= paddleRectOne.top)
  449.         {
  450.             center1 = where.right / 2;
  451.             center2 = paddleRectOne.right / 2;
  452.             
  453.             offset1 = (theWindow->portRect.right / (WidthCalc*3))+paddleRectOne.left;
  454.             offset2 = offset1+(theWindow->portRect.right / (WidthCalc*3));
  455.             offset3 = offset2+(theWindow->portRect.right / (WidthCalc*3));
  456.             
  457.             if(center1 < offset1)    
  458.                 pongSpeed.v *= -1,
  459.                 pongSpeed.h--;
  460.             
  461.             if(center1 > offset1 && center1 < offset2)
  462.                 pongSpeed.v *= -1;
  463.     
  464.             if(center1 > offset2 && center1 < offset3)
  465.                 pongSpeed.v *= -1,
  466.                 pongSpeed.h++;
  467.         }
  468.     }        
  469.     if(SectRect(&ballRect, &paddleRectTwo,&where))
  470.     {
  471.         if(ballRect.top-pongSpeed.v >= paddleRectTwo.bottom)
  472.         {
  473.             center1 = where.right / 2;
  474.             center2 = paddleRectTwo.right / 2;
  475.             
  476.             offset1 = (theWindow->portRect.right / (WidthCalc*3))+paddleRectTwo.left;
  477.             offset2 = offset1+(theWindow->portRect.right / (WidthCalc*3));
  478.             offset3 = offset2+(theWindow->portRect.right / (WidthCalc*3));
  479.             
  480.             if(center1 < offset1)
  481.                 pongSpeed.v *= -1,
  482.                 pongSpeed.h--;
  483.             
  484.             if(center1 > offset1 && center1 < offset2)
  485.                 pongSpeed.v *= -1;
  486.                 
  487.             if(center1 > offset2 && center1 < offset3)
  488.                 pongSpeed.v *= -1,
  489.                 pongSpeed.h++;
  490.         }
  491.     }    
  492.     if(pongSpeed.h > PADDLESPEED)
  493.         pongSpeed.h = PADDLESPEED;
  494.     if(pongSpeed.v > PADDLESPEED)
  495.         pongSpeed.v = PADDLESPEED;
  496.     if(pongSpeed.h < -PADDLESPEED)
  497.         pongSpeed.h = -PADDLESPEED;
  498.     if(pongSpeed.v < -PADDLESPEED)
  499.         pongSpeed.v = -PADDLESPEED;
  500.     
  501.     OffsetRect(&ballRect, pongSpeed.h, pongSpeed.v);
  502.                 
  503.     RGBBackColor(&white);
  504.     CopyBits(    &((GrafPtr)ball)->portBits,
  505.                 &((GrafPtr)theWindow)->portBits,
  506.                 &ball->portRect,
  507.                 &ballRect,
  508.                 0,
  509.                 NULL);
  510. }
  511.  
  512. GWorldPtr CreateOffscreen(Rect GWorldRect)
  513. {
  514.     QDErr        myQDErr;
  515.     GWorldPtr     worldForMe;
  516.     
  517.  
  518.     myQDErr = NewGWorld( &worldForMe, 0, &GWorldRect, NULL, NULL, useTempMem );
  519.     if (myQDErr != noErr)
  520.     {
  521.         DebugStr("\pOh no no memory!");
  522.         return nil;
  523.     }
  524.     
  525.     SetupOffscreen(worldForMe);
  526.     
  527.     return worldForMe;
  528. }
  529.  
  530. void    SetupOffscreen(GWorldPtr GWorld)
  531. {
  532.     LockPixels( GetGWorldPixMap( GWorld ) );
  533.     SetPort((GrafPtr)GWorld);
  534.     PaintRect(&GWorld->portRect);
  535. }
  536.  
  537.  
  538. void    CreatePaddles(WindowPtr theWindow)
  539. {
  540.     short        width,height;
  541.     Rect        paddlePortRect, paddleRect;
  542.     
  543.     
  544.     width = (theWindow->portRect.right -  theWindow->portRect.left) / WidthCalc;
  545.     height = (theWindow->portRect.bottom - theWindow->portRect.top) / HeightCalc;
  546.     
  547.     SetRect(&paddlePortRect, 0, 0, width + (PADDLESPEED << 1), height);
  548.     paddleRectOne = paddleRectTwo = paddlePortRect;
  549.  
  550.     OffsetRect(&paddleRectOne, theWindow->portRect.right/2-width,theWindow->portRect.bottom-height*2);
  551.     OffsetRect(&paddleRectTwo, theWindow->portRect.right/2-width,theWindow->portRect.top+height);
  552.  
  553.     SetRect(&paddleRect, PADDLESPEED, 0, width + PADDLESPEED, height);
  554.  
  555.     if (paddleOne == nil)
  556.         paddleOne = CreateOffscreen(paddlePortRect);
  557.         
  558.     SetPort((GrafPtr)paddleOne);
  559.  
  560.     RGBForeColor(&black);
  561.     PaintRect(&paddleOne->portRect);
  562.             
  563.     RGBForeColor(&green);
  564.     PaintRect(&paddleRect);
  565.     
  566.     RGBForeColor(&lightgreen);
  567.     
  568.     PenSize(2,2);
  569.     FrameRect(&paddleRect);    
  570.     
  571.     
  572.     if (paddleTwo == nil)
  573.         paddleTwo = CreateOffscreen(paddlePortRect);
  574.         
  575.     SetPort((GrafPtr)paddleTwo);
  576.  
  577.     RGBForeColor(&black);
  578.     PaintRect(&paddleTwo->portRect);
  579.     
  580.     RGBForeColor(&red);
  581.     PaintRect(&paddleRect);
  582.     
  583.     RGBForeColor(&lightred);
  584.     
  585.     PenSize(2,2);
  586.     FrameRect(&paddleRect);
  587. }
  588.  
  589. void    CreateBall(WindowPtr theWindow)
  590. {
  591.     short    width,height;
  592.     Rect    ballR;
  593.     
  594.  
  595.     width = (theWindow->portRect.right -  theWindow->portRect.left) / HeightCalc;
  596.     height = (theWindow->portRect.bottom - theWindow->portRect.top) / HeightCalc;
  597.     
  598.     SetRect(&ballRect, 0,0, width + (BALLSPEED << 1) + 3, height + (BALLSPEED << 1) + 3);
  599.     SetRect(&ballR, 0 + BALLSPEED + 2, 0 + BALLSPEED + 2, width, height);
  600.     
  601.     if (ball == nil)
  602.         ball = CreateOffscreen(ballRect);
  603.         
  604.     SetPort((GrafPtr)ball);
  605.     
  606.     RGBForeColor(&black);
  607.     PaintRect(&ball->portRect);
  608.     
  609.     RGBForeColor(&blue);
  610.     
  611.     PaintOval(&ballR);
  612.     
  613.     RGBForeColor(&lightblue);
  614.     
  615.     PenSize(1, 1);
  616.     FrameOval(&ballR);
  617.     
  618.     OffsetRect(&ballRect, 20, 20);
  619. }
  620.  
  621.  
  622. void InitPong(WindowPtr theWindow)
  623. {
  624.     GrafPtr        oldPort;
  625.     
  626.     
  627.     GetPort(&oldPort);
  628.     
  629.     if (pongGWorld == nil)
  630.         pongGWorld = CreateOffscreen(theWindow->portRect);
  631.     
  632.     if (pongGWorld == nil)
  633.     {
  634.         DebugStr("\pOh shit again!");
  635.         return;
  636.     }
  637.         
  638.     SetPort(theWindow);
  639.  
  640.     RGBForeColor(&black);
  641.     PaintRect(&theWindow->portRect);
  642.  
  643.     CreatePaddles(theWindow);
  644.     CreateBall(theWindow);
  645.     
  646.     PenNormal();
  647.     
  648.     pongSpeed.h = BALLSPEED;
  649.     pongSpeed.v = BALLSPEED;
  650.     
  651.     pongWindow = theWindow;
  652.     
  653.     SetPort(oldPort);
  654. }
  655.  
  656.  
  657. void DisposePong(void)
  658. {
  659.     if (ball != nil)
  660.         DisposePtr((Ptr)ball);
  661.     ball = nil;
  662.     if (paddleOne != nil)
  663.         DisposePtr((Ptr)paddleOne);
  664.     paddleOne = nil;
  665.     if (paddleTwo != nil)
  666.         DisposePtr((Ptr)paddleTwo);
  667.     paddleTwo = nil;
  668.     if (pongGWorld != nil)
  669.         DisposePtr((Ptr)pongGWorld);
  670.     pongGWorld = nil;
  671. }
  672.  
  673.  
  674. #pragma mark -
  675.  
  676.  
  677. void DoBreakOut(WindowPtr theWindow, EventRecord * theEvent)
  678. {
  679.     UpdateBreakoutPaddle(theWindow, theEvent);
  680.     UpdateBreakoutBall(theWindow);
  681. }
  682.  
  683.  
  684. void UpdateBreakoutPaddle(WindowPtr theWindow, EventRecord * theEvent)
  685. {
  686.     Boolean            handled = FALSE;
  687.  
  688.  
  689.     if(KeyIsDown(aKey))
  690.     {
  691.         if(boPaddleRect.left > 0)
  692.                     OffsetRect(&boPaddleRect, -PADDLESPEED, 0);
  693.         handled = TRUE;
  694.     }
  695.     if(KeyIsDown(sKey))
  696.     {
  697.         if(boPaddleRect.right < theWindow->portRect.right)
  698.                     OffsetRect(&boPaddleRect, PADDLESPEED, 0);
  699.         handled = TRUE;
  700.     }
  701.     if(KeyIsDown(fourKey))
  702.     {
  703.         if(boPaddleRect.left > 0)
  704.                     OffsetRect(&boPaddleRect, -PADDLESPEED, 0);
  705.         handled = TRUE;
  706.     }
  707.     if(KeyIsDown(sixKey))
  708.     {
  709.         if(boPaddleRect.right < theWindow->portRect.right)
  710.                     OffsetRect(&boPaddleRect, PADDLESPEED, 0);
  711.         handled = TRUE;
  712.     }
  713.     if (KeyIsDown(fiveKey) || KeyIsDown(threeKey) || KeyIsDown(oneKey))
  714.         handled = TRUE;
  715.     
  716.  
  717.     RGBBackColor(&white);
  718.     CopyBits(    &((GrafPtr)boPaddle)->portBits,
  719.                     &((GrafPtr)theWindow)->portBits,
  720.                     &boPaddle->portRect,
  721.                     &boPaddleRect,
  722.                     0,
  723.                     NULL);
  724.                         
  725.     if (theEvent != nil && handled)
  726.     {
  727.         theEvent->what = nullEvent;
  728.     }
  729. }
  730.  
  731. void UpdateBreakoutBall(WindowPtr theWindow)
  732. {    
  733.     Rect    where;
  734.     short    center1,center2,offset1,offset2, offset3;
  735.     
  736.  
  737.     if(boBallRect.right >= theWindow->portRect.right)
  738.         boSpeed.h *= -1;
  739.     if(boBallRect.left <= 0)
  740.         boSpeed.h *= -1;
  741.     if(boBallRect.bottom >= theWindow->portRect.bottom)
  742.         boSpeed.v *= -1;
  743.     if(boBallRect.top <= 0)
  744.         boSpeed.v *= -1;
  745.     
  746.     if(SectRect(&boBallRect, &boPaddleRect, &where))
  747.     {
  748.         if(boBallRect.bottom-boSpeed.v <= boPaddleRect.top)
  749.         {
  750.             center1 = where.right / 2;
  751.             center2 = boPaddleRect.right / 2;
  752.             
  753.             offset1 = (theWindow->portRect.right / (WidthCalc*5))+boPaddleRect.left;
  754.             offset2 = offset1+(theWindow->portRect.right / (WidthCalc*5));
  755.             offset3 = offset2+(theWindow->portRect.right / (WidthCalc*5));
  756.             
  757.             if(center1 < offset1)    
  758.                 boSpeed.v *= -1,
  759.                 boSpeed.h++;
  760.             
  761.             if(center1 > offset1 && center1 < offset2)
  762.                 boSpeed.v *= -1;
  763.     
  764.             if(center1 > offset2 && center1 < offset3)
  765.                 boSpeed.v *= -1,
  766.                 boSpeed.h--;
  767.         }
  768.     }        
  769.  
  770.     if(boSpeed.h > BALLSPEED)
  771.         boSpeed.h = BALLSPEED;
  772.     if(boSpeed.v > BALLSPEED)
  773.         boSpeed.v = BALLSPEED;
  774.     if(boSpeed.h < -BALLSPEED)
  775.         boSpeed.h = -BALLSPEED;
  776.     if(boSpeed.v < -BALLSPEED)
  777.         boSpeed.v = -BALLSPEED;
  778.             
  779.     OffsetRect(&boBallRect, boSpeed.h, boSpeed.v);
  780.                 
  781.     RGBBackColor(&white);
  782.     CopyBits(    &((GrafPtr)boBall)->portBits,
  783.                 &((GrafPtr)theWindow)->portBits,
  784.                 &boBall->portRect,
  785.                 &boBallRect,
  786.                 0,
  787.                 NULL);
  788.  
  789.     CheckCollide(theWindow);
  790. }
  791.  
  792.  
  793. void    CheckCollide(WindowPtr theWindow)
  794. {
  795.     short    i,j;
  796.     Rect    where;
  797.     
  798.     for(i = 0;i < BricksH; i++)
  799.     {
  800.         for(j = 0;j < BricksV; j++)
  801.         {
  802.             if(BrickState[i][j] != kHit)
  803.             {
  804.                 if(SectRect(&boBallRect, &Bricks[i][j], &where))
  805.                 {
  806.                     SysBeep(9);
  807.                     BrickState[i][j] = kHit;
  808.                     boSpeed.v *= -1;
  809.                     DrawBricks(theWindow);
  810.                     return;
  811.                 }
  812.             }
  813.         }
  814.     }
  815. }
  816.  
  817.  
  818. void    CreateBreakoutPaddle(WindowPtr theWindow)
  819. {
  820.     short        width,height;
  821.     Rect        paddlePortRect, paddleRect;
  822.     
  823.     
  824.     width = (theWindow->portRect.right -  theWindow->portRect.left) / WidthCalc;
  825.     height = (theWindow->portRect.bottom - theWindow->portRect.top) / HeightCalc;
  826.     
  827.     SetRect(&paddlePortRect, 0, 0, width + (PADDLESPEED << 1) + 4, height);
  828.     boPaddleRect = paddlePortRect;
  829.  
  830.     OffsetRect(&boPaddleRect, theWindow->portRect.right/2-width,theWindow->portRect.bottom-height*2);
  831.  
  832.     SetRect(&paddleRect, PADDLESPEED + 1, 0, width + PADDLESPEED + 1, height);
  833.  
  834.     if (boPaddle == nil)
  835.         boPaddle = CreateOffscreen(paddlePortRect);
  836.         
  837.     if (boPaddle == nil)
  838.     {
  839.         DebugStr("\pboPaddle nil");
  840.         return;
  841.     }
  842.         
  843.     RGBForeColor(&green);
  844.     PaintRect(&paddleRect);
  845.     
  846.     RGBForeColor(&lightgreen);
  847.     
  848.     PenSize(2,2);
  849.     FrameRect(&paddleRect);    
  850. }
  851.  
  852.  
  853. void    CreateBreakoutBall(WindowPtr theWindow)
  854. {
  855.     short    width,height;
  856.     Rect    ballR;
  857.     
  858.  
  859.     width = (theWindow->portRect.right - theWindow->portRect.left) / HeightCalc;
  860.     height = (theWindow->portRect.bottom - theWindow->portRect.top) / HeightCalc;
  861.     
  862.     SetRect(&boBallRect, 0,0, width + (BALLSPEED << 1) + 3, height + (BALLSPEED << 1) + 3);
  863.     SetRect(&ballR, 0 + BALLSPEED + 2, 0 + BALLSPEED + 2, width, height);
  864.     
  865.     if (boBall == nil)
  866.         boBall = CreateOffscreen(boBallRect);
  867.         
  868.     if (boBall == nil)
  869.     {
  870.         DebugStr("\pboBall nil");
  871.         return;
  872.     }
  873.  
  874.     RGBForeColor(&blue);
  875.     
  876.     PaintOval(&ballR);
  877.     
  878.     RGBForeColor(&lightblue);
  879.     
  880.     PenSize(1, 1);
  881.     FrameOval(&ballR);
  882.     
  883.     OffsetRect(&boBallRect, 20, BrickHeight * 5);
  884. }
  885.  
  886.  
  887. void    CreateBricks(WindowPtr    window)
  888. {
  889.     short    width, height;
  890.     short    i,j;
  891.     
  892.     width = BrickWidth = (window->portRect.right - BricksH) / BricksH;
  893.     height = BrickHeight = window->portRect.bottom / HeightCalc;
  894.     
  895.     SetRect(&brickRect, 0, 0, width, height);
  896.     
  897.     if (brickWorld == nil)
  898.         brickWorld = CreateOffscreen(brickRect);
  899.     
  900.     if (brickWorld == nil)
  901.     {
  902.         DebugStr("\pbricks nil");
  903.         return;
  904.     }
  905.     
  906.     RGBForeColor(&red);
  907.     PaintRect(&brickRect);
  908.     
  909.     PenSize(2,2);
  910.     RGBForeColor(&lightred);
  911.     FrameRect(&brickRect);
  912.     
  913.     for(i = 0;i < BricksH; i++)
  914.     {
  915.         for(j = 0;j < BricksV; j++)
  916.         {
  917.             SetRect(&Bricks[i][j], i+1+i*BrickWidth, j+1+j*BrickHeight, i+1+i*BrickWidth+BrickWidth, j+1+j*BrickHeight+BrickHeight);
  918.             BrickState[i][j] = kSafe;
  919.         }
  920.     }
  921. }
  922.  
  923. void    DrawBricks(WindowPtr theWindow)
  924. {
  925.     short    i,j;
  926.     Rect    where;
  927.     
  928.     for(i = 0;i < BricksH; i++)
  929.         for(j = 0;j < BricksV; j++)
  930.         {
  931.             if(BrickState[i][j] != kHit)
  932.             {
  933.                 SetRect(&where, i+1+i*BrickWidth, j+1+j*BrickHeight, i+1+i*BrickWidth+BrickWidth, j+1+j*BrickHeight+BrickHeight);
  934.                 RGBBackColor(&white);
  935.                 CopyBits(    &((GrafPtr)brickWorld)->portBits,
  936.                     &((GrafPtr)theWindow)->portBits,
  937.                     &brickWorld->portRect,
  938.                     &where,
  939.                     0,
  940.                     NULL);
  941.             }
  942.             else
  943.             {
  944.                 SetPort((GrafPtr)theWindow);
  945.                 RGBForeColor(&black);
  946.                 PaintRect(&Bricks[i][j]);
  947.             }
  948.         }
  949. }
  950.  
  951.  
  952. void InitBreakOut(WindowPtr theWindow)
  953. {
  954.     GrafPtr        oldPort;
  955.     
  956.     
  957.     GetPort(&oldPort);
  958.     
  959.     if (boGWorld == nil)
  960.         boGWorld = CreateOffscreen(theWindow->portRect);
  961.     
  962.     if (boGWorld == nil)
  963.     {
  964.         DebugStr("\pboGWorld nil");
  965.         return;
  966.     }
  967.         
  968.     SetPort(theWindow);
  969.  
  970.     RGBForeColor(&black);
  971.     PaintRect(&theWindow->portRect);
  972.  
  973.     CreateBricks(theWindow);
  974.     CreateBreakoutPaddle(theWindow);
  975.     CreateBreakoutBall(theWindow);
  976.     DrawBricks(theWindow);
  977.     
  978.     PenNormal();
  979.     
  980.     boSpeed.h = BALLSPEED;
  981.     boSpeed.v = BALLSPEED;
  982.     
  983.     breakoutWindow = theWindow;
  984.     
  985.     SetPort(oldPort);
  986. }
  987.  
  988.  
  989. void DisposeBreakOut(void)
  990. {
  991.     if (boBall != nil)
  992.         DisposePtr((Ptr)boBall);
  993.     boBall = nil;
  994.     if (boPaddle != nil)
  995.         DisposePtr((Ptr)boPaddle);
  996.     boPaddle = nil;
  997.     if (boGWorld != nil)
  998.         DisposePtr((Ptr)boGWorld);
  999.     boGWorld = nil;
  1000. }
  1001.